--- /dev/null
+/*
+ Utilities for parsing Comma Seperated Value files (CSV)
+
+ Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include <ctype.h>
+#include <unistd.h>
+#include "defs.h"
+#include "csv_util.h"
+
+#define MYNAME "CSV_UTIL"
+
+/*********************************************************************/
+/* csv_stringclean() - remove any unwanted characters from string. */
+/* returns MODIFIED string. */
+/* usage: csv_stringclean(stringtoclean, "&,\"") */
+/* (strip out ampersands, commas, and quotes. */
+/*********************************************************************/
+char *
+csv_stringclean(char *string, const char *chararray) {
+ char * p;
+ char * lp;
+ const char * cp;
+
+ if ((! string) || (! chararray)) {
+ return (string);
+ }
+
+ /* lp - end of the original string */
+ lp = string;
+ while (*lp) lp++;
+
+ cp = chararray;
+ while (*cp) {
+
+
+ p = string;
+ while (*p) {
+ if (*cp == *p) {
+ /* we don't want this character! */
+ strncpy(p, p+1, (lp - p));
+ }
+ p++;
+ }
+ cp++;
+ }
+
+ return (string);
+}
+
+
+/***********************************************************************************/
+/* csv_stringtrim() - trim whitespace and leading and trailing enclosures (quotes) */
+/* returns MODIFIED string. */
+/* usage: csv_stringtrim(string, "\"") */
+/***********************************************************************************/
+char *
+csv_stringtrim(char *string, const char *enclosure)
+{
+ static char *p1 = NULL;
+ char *p2 = NULL;
+ size_t elen;
+
+ if (!string) {
+ return (string);
+ }
+
+ if (!enclosure) {
+ elen = 0;
+ } else {
+ elen = strlen(enclosure);
+ }
+
+ p2 = string;
+
+ /* advance pointer to the end of the string */
+ while ((*p2) && (p2++)) {
+ }
+ p2--;
+
+ /* trim off trailing whitespace */
+ while (isspace(*p2)) {
+ *p2 = '\0';
+ p2--;
+ }
+
+ p1 = string;
+
+ /* advance p1 past any leading whitespace */
+ while (isspace(*p1)) {
+ p1++;
+ }
+
+ /* if we have enclosures, yank them out in pairs */
+ if (elen) {
+ while ((strncmp(p1, enclosure, elen) == 0)
+ && (strncmp(p2, enclosure, elen) == 0)) {
+ *p2 = '\0';
+ p2--;
+ p1++;
+ }
+ }
+
+ return (p1);
+}
+
+/*****************************************************************************/
+/* csv_lineparse() - extract data fields from a delimited string. designed */
+/* to handle quoted and delimited data within quotes. */
+/* returns temporary COPY of delimited data field (use it */
+/* or lose it). */
+/* usage: p = csv_lineparse(string, ",", "\"", line) [initial call] */
+/* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */
+/*****************************************************************************/
+char *
+csv_lineparse(char *stringstart, const char *delimited_by,
+ const char *enclosed_in, const int line_no)
+{
+ char *sp;
+ static char *p = NULL;
+ static char *tmp = NULL;
+ size_t dlen, elen;
+ int enclosedepth = 0;
+ short int dfound;
+
+ if (!p) {
+ /* first pass thru */
+ p = stringstart;
+
+ if (!p) {
+ /* last pass out */
+ return (NULL);
+ }
+ }
+
+ if (tmp) {
+ free(tmp);
+ tmp = NULL;
+ }
+
+ /* the beginning of the string we start with (this pass) */
+ sp = p;
+
+ /* length of delimiters and enclosures */
+ dlen = strlen(delimited_by);
+ elen = strlen(enclosed_in);
+
+ dfound = 0;
+
+ while ((*p) && (!dfound)) {
+ if (strncmp(p, enclosed_in, elen) == 0) {
+ if (enclosedepth)
+ enclosedepth--;
+ else
+ enclosedepth++;
+ }
+
+ if ((!enclosedepth) && (strncmp(p, delimited_by, dlen) == 0)) {
+ dfound = 1;
+
+ } else {
+ p++;
+ }
+ }
+
+ /* allocate enough space for this data field */
+ tmp = (char *) calloc((p - sp) + 1, sizeof(char));
+
+ if (!tmp) {
+ fatal(MYNAME ": cannot allocate memory\n");
+ }
+
+ strncpy(tmp, sp, (p - sp));
+
+ if (dfound) {
+ /* skip over the delimited_by */
+ p += dlen;
+ } else {
+ /* end of the line */
+ p = NULL;
+ }
+
+ if (enclosedepth != 0) {
+ fprintf(stderr, "%s: Warning- Unbalanced Field Enclosures (%s) on line %d\n",
+ MYNAME, enclosed_in, line_no);
+ }
+
+ return (tmp);
+}
--- /dev/null
+/*
+ Copyright (C) 2002 Alex Mottram (geo_alexm at cox-internet.com)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+/* function prototypes */
+char *
+csv_stringtrim(char *string, const char *enclosure);
+
+char *
+csv_lineparse(char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no);
+
+char *
+csv_stringclean(char *string, const char *chararray);
--- /dev/null
+/*
+ OziExplorer Waypoint File Version 1.1 Format (.wpt)
+ Fixed-Length Comma Delimited
+
+ Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com)
+
+ As described in Maptech Terrain Navigator Help File.
+ Tested against Terrain Navigator and ExpertGPS import/export .MXF files.
+
+ Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include "csv_util.h"
+#include <ctype.h>
+#include <math.h> /* for floor */
+
+#define MYNAME "OZI"
+
+static FILE *file_in;
+static FILE *file_out;
+
+static void
+rd_init(const char *fname)
+{
+ file_in = fopen(fname, "r");
+ if (file_in == NULL) {
+ fatal(MYNAME ": Cannot open %s for reading\n", fname);
+ }
+}
+
+static void
+rd_deinit(void)
+{
+ fclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+ file_out = fopen(fname, "w");
+ if (file_out == NULL) {
+ fatal(MYNAME ": Cannot open %s for writing\n", fname);
+ }
+}
+
+static void
+wr_deinit(void)
+{
+ fclose(file_out);
+}
+
+static void
+data_read(void)
+{
+ char buff[1024];
+ char *s;
+ waypoint *wpt_tmp;
+ int i;
+ int linecount = 0;
+
+ do {
+ linecount++;
+ memset(&buff, '\0', sizeof(buff));
+ fgets(buff, sizeof(buff), file_in);
+
+ if ((strlen(buff)) && (strstr(buff, ",") != NULL)) {
+
+ wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+
+ if (wpt_tmp == NULL) {
+ fatal(MYNAME ": cannot allocate memory\n");
+ }
+
+ /* data delimited by commas, possibly enclosed in quotes. */
+ s = buff;
+ s = csv_lineparse(s, ",", "\"", linecount);
+
+ i = 0;
+ while (s) {
+ switch (i) {
+ case 0:
+ /* sequence # */
+ break;
+ case 1:
+ /* waypoint name */
+ wpt_tmp->shortname = strdup(s);
+
+ if (! wpt_tmp->shortname)
+ fatal(MYNAME, ": cannot allocate memory\n");
+
+ csv_stringtrim(wpt_tmp->shortname, "");
+ break;
+ case 2:
+ /* degrees latitude */
+ wpt_tmp->position.latitude.degrees = atof(s);
+ break;
+ case 3:
+ /* degrees longitude */
+ wpt_tmp->position.longitude.degrees = atof(s);
+ break;
+ case 4:
+ /* DAYS since 1900 00:00:00 in days.days (5.5) */
+ wpt_tmp->creation_time = (atof(s) - 25569.0) * 86400.0;
+ break;
+ case 5:
+ /* icons 0-xx */
+ break;
+ case 6:
+ /* unknown - always 1 */
+ break;
+ case 7:
+ /* display format options 0-8 */
+ break;
+ case 8:
+ /* foreground color (0=black) */
+ break;
+ case 9:
+ /* background color (65535=yellow)*/
+ break;
+ case 10:
+ /* Description */
+ wpt_tmp->description = strdup(s);
+
+ if (! wpt_tmp->description)
+ fatal(MYNAME, ": cannot allocate memory\n");
+
+ wpt_tmp->description = csv_stringtrim(wpt_tmp->description, "");
+
+ break;
+ case 11:
+ /* pointer direction 0,1,2,3 bottom,top,left,right */
+ break;
+ case 12:
+ /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */
+ break;
+ case 13:
+ /* proximity distance - meters */
+ break;
+ case 14:
+ /* altitude in feet */
+ wpt_tmp->position.altitude.altitude_meters = (atof(s) * .3048);
+ break;
+ case 15:
+ /* waypoint text name size */
+ break;
+ case 16:
+ /* bold checkbox (1=bold, default 0) */
+ break;
+ case 17:
+ /* symbol size - 17 default */
+ break;
+ default:
+ /* whoa! nelly */
+ fprintf (stderr, "%s: Warning: data fields on line %d exceed specification.\n",
+ MYNAME, linecount);
+ break;
+ }
+ i++;
+
+ s = csv_lineparse(NULL, ",", "\"", linecount);
+ }
+
+ waypt_add(wpt_tmp);
+
+ } else {
+ /* empty line */
+ }
+
+ } while (!feof(file_in));
+}
+
+static void
+ozi_disp(waypoint * wpt)
+{
+ static int index = 0;
+ double alt_feet;
+ double ozi_time;
+
+ ozi_time = (wpt->creation_time / 86400.0) + 25569.0;
+ alt_feet = (wpt->position.altitude.altitude_meters * 3.2808);
+
+ csv_stringclean(wpt->description, ",");
+ csv_stringclean(wpt->shortname, ",");
+
+ index++;
+
+ fprintf(file_out, "%4d,%-14.14s,%11.6f,%11.6f,%011.5f,%3d,%2d,%2d,%10d,%10d,%-40.40s,%2d,%2d,%5d,%7.0f,%2d,%2d,%2d\n",
+ index, wpt->shortname, wpt->position.latitude.degrees,
+ wpt->position.longitude.degrees, ozi_time, 0, 1, 3, 0, 65535,
+ wpt->description, 0, 0, 0, alt_feet, 6, 0, 17);
+
+}
+
+static void
+data_write(void)
+{
+
+ fprintf(file_out, "OziExplorer Waypoint File Version 1.1\n");
+ fprintf(file_out, "WGS 84\n");
+ fprintf(file_out, "Reserved 2\n");
+ fprintf(file_out, "Reserved 3\n");
+
+ waypt_disp_all(ozi_disp);
+}
+
+ff_vecs_t ozi_vecs = {
+ rd_init,
+ wr_init,
+ rd_deinit,
+ wr_deinit,
+ data_read,
+ data_write,
+};
+
--- /dev/null
+OziExplorer Waypoint File Version 1.1
+WGS 84
+Reserved 2
+Reserved 3
+ 1,GCEBB , 35.972033, -87.134700,25569.00000, 0, 1, 3, 0, 65535,Mountain Bike Heaven by susy1313 , 0, 0, 0, 0, 6, 0,17
+ 2,GC1A37 , 36.090683, -86.679550,25569.00000, 0, 1, 3, 0, 65535,The Troll by a182pilot & Family , 0, 0, 0, 0, 6, 0,17
+ 3,GC1C2B , 35.996267, -86.620117,25569.00000, 0, 1, 3, 0, 65535,Dive Bomber by JoGPS & family , 0, 0, 0, 0, 6, 0,17
+ 4,GC25A9 , 36.038483, -86.648617,25569.00000, 0, 1, 3, 0, 65535,FOSTER by JoGPS & Family , 0, 0, 0, 0, 6, 0,17
+ 5,GC2723 , 36.112183, -86.741767,25569.00000, 0, 1, 3, 0, 65535,Logan Lighthouse by JoGps & Family , 0, 0, 0, 0, 6, 0,17
+ 6,GC2B71 , 36.064083, -86.790517,25569.00000, 0, 1, 3, 0, 65535,Ganier Cache by Susy1313 , 0, 0, 0, 0, 6, 0,17
+ 7,GC309F , 36.087767, -86.809733,25569.00000, 0, 1, 3, 0, 65535,Shy's Hill by FireFighterEng33 , 0, 0, 0, 0, 6, 0,17
+ 8,GC317A , 36.057500, -86.892000,25569.00000, 0, 1, 3, 0, 65535,GittyUp by JoGPS / Warner Parks , 0, 0, 0, 0, 6, 0,17
+ 9,GC317D , 36.082800, -86.867283,25569.00000, 0, 1, 3, 0, 65535,Inlighting by JoGPS / Warner Parks , 0, 0, 0, 0, 6, 0,17